<?php

function digest($seed, $pw) {
	if (!pw) {
		return null;
	}
	return md5($seed . $pw);
}

class RconClient {
	private $sock = null;
	private $trace = true;
	private $challenge = null;
	
	function __construct() {
		$this->sock= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		if ($socket === false) {
			echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
		} else {
			echo "socket_create() success.\n";
		}
	}
	
	function __destruct() {
		socket_shutdown($this->sock, 1);
		socket_close($this->sock);
	}
	
	function connect($host, $port) {
		$result = socket_connect($this->sock, $host, $port);
		if ($result === false) {
			echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
		} else {
			echo "socket_connect() success.\n";
		}
		
		$response = $this->getWelcomeResponse();
		
		# Dig out the seed
		$prefix = '### Digest seed: ';
		$challpos = strpos($response, $prefix);
		$header = substr($response, $challpos);
		if ($challpos) {
			$challpos += strlen($prefix);
			$challend = strpos($response, "\n", $challpose);
			$this->challenge = substr($response, $challpos, $challend);
			if ($this->trace) {
				echo 'S: challenge: ', $this->challenge;
				echo 'S:', $response;
			}
		}
		
		return $header;
	}
	
	function invoke($cmd) {
		if ($this->trace) {
			echo 'C:', $cmd;
		}
		socket_write($this->sock, "\x02" . $cmd . "\n"); #This is a non-interactive command.
		$response = getResponse();
		if ($this->trace) {
			echo 'S:', $reponse;
		}
		
		return $reponse;
	}
	
	private function getWelcomeResponse() {
		$result = '';
		while (1) {
			$data = socket_read($this->sock, 1024);
			$result .= $data;
			$lflfpos = strpos($result, "\n\n");
			if ($lflfpos) {
				break;
			}
		}
		
		return $result;
	}
	
	private function getResponse() {
		
		$result = '';
		$done = false;
		while (!$done) {
			$data = socket_read($this->sock, 1024);
			$s = strlen($data);
			for ($i = 0; $i < $s; $i++) {
				if ($c === "\x04") {
					$done = true;
					break;
				}
				$result .= $c;
			}
		}
		
		return $result;
	}
}
?>